package cn.sdc.sfw.dao.handler.impl;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cn.sdc.sfw.dao.handler.ResultSetHandler;
import cn.sdc.sfw.dao.model.Bean;
import cn.sdc.sfw.dao.model.Beans;
import cn.sdc.sfw.dao.model.Property;
import cn.sdc.sfw.dao.model.PropertyType;
import cn.sdc.sfw.dao.types.DbType;
import cn.sdc.sfw.dao.types.DbTypes;
import cn.sdc.sfw.util.ClassUtil;
import cn.sdc.sfw.util.StringUtil;

public class BeanResultSetHandlerImpl implements ResultSetHandler {

	private Class beanClass;

	private Bean bean;
	
	private Boolean listFlg;

	public BeanResultSetHandlerImpl(Class beanClass,Boolean listFlg) {
		setBeanClass(beanClass);
		this.listFlg = listFlg;
	}

	public BeanResultSetHandlerImpl(Class beanClass) {
		setBeanClass(beanClass);
		this.listFlg = false;
	}
	
	public Class getBeanClass() {
		return beanClass;
	}

	public void setBeanClass(Class beanClass) {
		this.beanClass = beanClass;
		bean = Beans.getBean(beanClass);
	}

	protected PropertyType[] createPropertyTypes(ResultSetMetaData rsmd)
		throws SQLException {
	
		int count = rsmd.getColumnCount();
		PropertyType[] propertyTypes = new PropertyType[count];
		for (int i = 0; i < count; ++i) {
			String columnName = rsmd.getColumnLabel(i + 1);
			String propertyName = StringUtil.replace(columnName, "_", "");
			Property Property = bean.getProperty(propertyName);
			DbType dbType = DbTypes.getDbType(Property.getPropertyType());
			propertyTypes[i] = new PropertyType(Property, dbType, columnName);
		}
		return propertyTypes;
	}

	protected Object createRow(ResultSet rs, PropertyType[] propertyTypes)
			throws SQLException {
	
		Object row = ClassUtil.newInstance(beanClass);
		for (int i = 0; i < propertyTypes.length; ++i) {
			PropertyType pt = propertyTypes[i];
			DbType dbType = pt.getValueType();
			Object value = dbType.getValue(rs, i + 1);
			Property pd = pt.getProperty();
			pd.setValue(row, value);
		}
		return row;
	}

	@Override
	public Object handle(ResultSet rs) throws SQLException {
		if(listFlg){
			PropertyType[] propertyTypes = createPropertyTypes(rs.getMetaData());
			List list = new ArrayList();
			while (rs.next()) {
				Object row = createRow(rs, propertyTypes);
				list.add(row);
			}
			return list;
		}else if (rs.next()) {
			return createRow(rs, createPropertyTypes(rs.getMetaData()));
		} else {
			return null;
		}
	}
}